package discover

import (
	"context"
	"time"

	"github.com/lukeaxu/discover/registry"
	"google.golang.org/grpc"
	"google.golang.org/grpc/credentials/insecure"
)

type ClientOpt func(*Client)

type Client struct {
	registry registry.Registry
	insecure bool
	timeout  time.Duration
}

func ClientWithInsecure() ClientOpt {
	return func(c *Client) {
		c.insecure = true
	}
}

func ClientWithRegistry(r registry.Registry, d time.Duration) ClientOpt {
	return func(c *Client) {
		c.registry = r
		c.timeout = d
	}
}

func NewClient(opts ...ClientOpt) (*Client, error) {
	client := &Client{}
	for _, opt := range opts {
		opt(client)
	}
	return client, nil
}

func (c *Client) Dial(ctx context.Context, sn string, opts ...grpc.DialOption) (*grpc.ClientConn, error) {
	var target = sn
	dialOpts := make([]grpc.DialOption, 0)
	if c.registry != nil {
		rb, err := NewGrpcResolverBuilder(c.registry, c.timeout)
		if err != nil {
			return nil, err
		}
		dialOpts = append(dialOpts, grpc.WithResolvers(rb))
		target = rb.targetForServiceName(sn)
	}
	if c.insecure {
		dialOpts = append(dialOpts, grpc.WithTransportCredentials(insecure.NewCredentials()))
	}
	if len(opts) > 0 {
		dialOpts = append(dialOpts, opts...)
	}
	cc, err := grpc.DialContext(ctx, target, dialOpts...)
	return cc, err
}
